package za.ac.nmmu.muhelp.util;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;



public class HTTPUtilities {

    private static Logger log = Logger.getLogger(HTTPUtilities.class.getName());

    public static String defaultErrorMessage= "{\"success\":false}";


private static String prependGateway(String urlString) {
	log.info("urlString is " + urlString);
	try {
		return urlString;
	}
	catch ( Throwable t ) {
		log.info("can't find gateway properties file " + t);
	}
	return urlString;
}

public static String getPage(String urlString ) {
       log.info("getPage urlString is " + urlString);
       try {
        	URL url = null;
        	InputStream inputStream = null;
        	URLConnection urlConnection = null;

                url = new URL(urlString);

                inputStream = url.openStream();
                urlConnection = url.openConnection();


                int cnt = 0;
                int cntThisRead = 0;
		int max=8388608;
                byte buffer[] = new byte[max];
                boolean keepRunning = true;

                while ( /*( (cntThisRead = inputStream.available() ) > 0) &&*/ ( cnt < max) && (keepRunning) ) {
                        try {
                                cntThisRead = inputStream.read(buffer, cnt, max-cnt);
				if ( cntThisRead == -1 ) {
					log.info("cntThisRead is " + cntThisRead + " breaking loop");
					break;
				}
                                cnt += cntThisRead;
				log.info("cntThisRead " + cntThisRead + " cnt " + cnt);
                        }
                        catch ( Throwable t ) {
                                log.info("throwing " + t);
                        }
                }
		String st = new String(defaultErrorMessage);
		if ( cnt > 1 ) {
                	st = new String(buffer, 0, cnt);
			//log.info(st);
		}
		else {
			Map<String, List<String>> headers = urlConnection.getHeaderFields();
			if ( headers.size() > 0 ) {
				String header = urlConnection.getHeaderField(0);
				//log.info("header is " + header);
			}
		}
		return st;
	}
	catch ( Throwable t ) {
		log.info("problem getting webaddress " + t);
	}

	return defaultErrorMessage;

}

private static String getViaGateway(String urlString ) {
	return prependGateway(urlString);
}

public static String get(String urlString ) {
	//
	// as per Thane, the protocol might not
	// be there
	//
	if ( ! urlString.startsWith("http://") )
		urlString = new String("http://" + urlString);
	return getPage(getViaGateway(urlString));
}


public static String postPage(String urlString, String payload ) {
       log.info("postPage urlString is " + urlString);
       try {
        	URL url = null;
        	InputStream inputStream = null;
 		OutputStream outputStream = null;
        	URLConnection urlConnection = null;

                url = new URL(urlString);
                //log.info("url is " + url);

                urlConnection = url.openConnection();
                //log.info("urlConnection is " + urlConnection);

		urlConnection.setDoOutput(true);
		outputStream = urlConnection.getOutputStream();
		//log.info("outputStream is " + outputStream);
		outputStream.write(payload.getBytes());
		//log.info("written");
		outputStream.flush();
		//log.info("flushed");
		//outputStream.close();
		//log.info("closed");


		
		//urlConnection.setDoInput(true);
		//log.info("trying to get inputStream");
		inputStream = urlConnection.getInputStream();
		//log.info("inputStream is " + inputStream);
                int cnt = 0;
                int cntThisRead = 0;
                int max=1048576;
                byte buffer[] = new byte[max];
                boolean keepRunning = true;

                //log.info("waiting for reply");
                while ( /*( (cntThisRead = inputStream.available() ) > 0) &&*/ ( cnt < max) && (keepRunning) ) {
                        try {
                                cntThisRead = inputStream.read(buffer, cnt, max-cnt);
				if ( cntThisRead == -1 )
					break;
                                cnt += cntThisRead;
                        }
                        catch ( Throwable t ) {
                                log.info("throwing " + t);
                        }
                }
		//log.info("finished");
		String st = new String(defaultErrorMessage);
		if ( cnt > 1 )
                	st = new String(buffer, 0, cnt);
		else {
			Map<String, List<String>> headers = urlConnection.getHeaderFields();
			if ( headers.size() > 0 ) {
				String header = urlConnection.getHeaderField(0);
				//log.info("header is " + header);
			}
		}
		return st;
	}
	catch ( Throwable t ) {
		log.info("problem getting webaddress " + t);
	}

	return defaultErrorMessage;

}

public static String putPage(String urlString, String payload ) {
       log.info("putPage urlString is " + urlString);
       try {
        	URL url = null;
        	InputStream inputStream = null;
 		OutputStream outputStream = null;
        	URLConnection urlConnection = null;

                url = new URL(urlString);
                //log.info("url is " + url);

                urlConnection = url.openConnection();
                //log.info("urlConnection is " + urlConnection);

		urlConnection.setDoOutput(true);
		if ( urlConnection instanceof HttpURLConnection ) {
			//log.info("httpURLConneciton");
			HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
			httpURLConnection.setRequestMethod("PUT");
		}
		outputStream = urlConnection.getOutputStream();
		//log.info("outputStream is " + outputStream);
		outputStream.write(payload.getBytes());
		//log.info("written");
		outputStream.flush();
		//log.info("flushed");
		//outputStream.close();
		//log.info("closed");


		
		//urlConnection.setDoInput(true);
		//log.info("trying to get inputStream");
		inputStream = urlConnection.getInputStream();
		//log.info("inputStream is " + inputStream);
                int cnt = 0;
                int cntThisRead = 0;
                int max=1048576;
                byte buffer[] = new byte[max];
                boolean keepRunning = true;

                //log.info("waiting for reply");
                while ( /*( (cntThisRead = inputStream.available() ) > 0) &&*/ ( cnt < max) && (keepRunning) ) {
                        try {
                                cntThisRead = inputStream.read(buffer, cnt, max-cnt);
				if ( cntThisRead == -1 )
					break;
                                cnt += cntThisRead;
                        }
                        catch ( Throwable t ) {
                                log.info("throwing " + t);
                        }
                }
		//log.info("finished");
		String st = new String(defaultErrorMessage);
		if ( cnt > 1 )
                	st = new String(buffer, 0, cnt);
		else {
			Map<String, List<String>> headers = urlConnection.getHeaderFields();
			if ( headers.size() > 0 ) {
				String header = urlConnection.getHeaderField(0);
				//log.info("header is " + header);
			}
		}
		return st;
	}
	catch ( Throwable t ) {
		log.info("problem getting webaddress " + t);
	}

	return defaultErrorMessage;

}

public static String deletePage(String urlString, String payload ) {
       log.info("deletePage urlString is " + urlString);
       try {
        	URL url = null;
        	InputStream inputStream = null;
 		OutputStream outputStream = null;
        	URLConnection urlConnection = null;

                url = new URL(urlString);
                //log.info("url is " + url);

                urlConnection = url.openConnection();
                //log.info("urlConnection is " + urlConnection);

		urlConnection.setDoOutput(true);
		HttpURLConnection httpURLConnection = null;
		if ( urlConnection instanceof HttpURLConnection ) {
			//log.info("httpURLConnection");
			httpURLConnection = (HttpURLConnection) urlConnection;
			httpURLConnection.setRequestMethod("DELETE");
		}
		//outputStream = urlConnection.getOutputStream();
		//log.info("outputStream is " + outputStream);
		//outputStream.write(payload.getBytes());
		//log.info("written");
		//outputStream.flush();
		//log.info("flushed");

		//outputStream.close();
		//log.info("closed");


		
		//urlConnection.setDoInput(true);
		//log.info("trying to get inputStream");
		inputStream = urlConnection.getInputStream();
		//log.info("inputStream is " + inputStream);
                int cnt = 0;
                int cntThisRead = 0;
                int max=1048576;
                byte buffer[] = new byte[max];
                boolean keepRunning = true;

                //log.info("waiting for reply");
                while ( /*( (cntThisRead = inputStream.available() ) > 0) &&*/ ( cnt < max) && (keepRunning) ) {
                        try {
                                cntThisRead = inputStream.read(buffer, cnt, max-cnt);
				if ( cntThisRead == -1 )
					break;
                                cnt += cntThisRead;
                        }
                        catch ( Throwable t ) {
                                log.info("throwing " + t);
                        }
                }
		//log.info("finished");
		String st = new String(defaultErrorMessage);
		if ( cnt > 1 )
                	st = new String(buffer, 0, cnt);
		else {
			Map<String, List<String>> headers = urlConnection.getHeaderFields();
			if ( headers.size() > 0 ) {
				String header = urlConnection.getHeaderField(0);
				//log.info("header is " + header);
			}
		}
		return st;
	}
	catch ( Throwable t ) {
		log.info("problem getting webaddress " + t);
	}

	return defaultErrorMessage;

}

public static String put(String urlString, String payload) {
	//
	// as per Thane, the protocol might not
	// be there
	//
	if ( ! urlString.startsWith("http://") )
		urlString = new String("http://" + urlString);
	return putPage(prependGateway(urlString), payload);
}

public static String post(String urlString, String payload) {
	//
	// as per Thane, the protocol might not
	// be there
	//
	if ( ! urlString.startsWith("http://") )
		urlString = new String("http://" + urlString);
	return postPage(prependGateway(urlString), payload);
}

public static String delete(String urlString, String payload) {
	//
	// as per Thane, the protocol might not
	// be there
	//
	if ( ! urlString.startsWith("http://") )
		urlString = new String("http://" + urlString);
	return deletePage(prependGateway(urlString), payload);
}

public static String delete(String urlString) {
	//
	// as per Thane, the protocol might not
	// be there
	//
	if ( ! urlString.startsWith("http://") )
		urlString = new String("http://" + urlString);
	return deletePage(prependGateway(urlString), "");
}
 
}
